<template>
  <div>
    <canvas id='canvas0' width='500' height='500'>
      Canvas not supported
    </canvas>
    <double-buffer-canvas ref='doubleBufferCanvas1' id='canvas1' width='500' height='500'>
      Double Buffer Canvas not supported
    </double-buffer-canvas>
    <canvas id='canvas2' width='500' height='500'>
      Canvas not supported
    </canvas>
    <div id="infoWindow">
      hello
    </div>
  </div>
</template>

<script>
  import {CanvasUtil} from './CanvasUtil';
  import DoubleBufferCanvas from './DoubleBufferCanvas'

  ///////////////////////////////////////////////////////////////////////////
  import icon_0 from './images/001用水区-输炼地区.png';
  import icon_1 from './images/002用水区-石化园区.png';
  import icon_2 from './images/002用水区域-石化园区.png';
  import icon_3 from './images/003用水区-上环.png';
  import icon_4 from './images/003用水区-自流环.png';
  import icon_5 from './images/004用水区-白碱滩.png';
  import icon_6 from './images/005用水区-下环.png';
  import icon_7 from './images/006用水区-中环.png';
  import icon_8 from './images/006用水区-乌尔禾.png';
  import icon_9 from './images/007用水区.png';
  import icon_10 from './images/1001泵站.png';
  import icon_11 from './images/101水厂.png';
  import icon_12 from './images/1101水源管理站.png';
  import icon_13 from './images/201管汇间.png';
  import icon_14 from './images/202管汇间.png';
  import icon_15 from './images/301普通阀门.png';
  import icon_16 from './images/302电控阀门.png';
  import icon_17 from './images/401流量计.png';
  import icon_18 from './images/501压力表.png';
  import icon_19 from './images/601水泵.png';
  import icon_20 from './images/701山顶水库.png';
  import icon_21 from './images/801清水池.png';
  import icon_22 from './images/901三坪水库.png';
  import icon_23 from './images/901山坪水库.png';
  import icon_24 from './images/902调节水库.png';
  import icon_25 from './images/903黄羊水库.png';
  import icon_26 from './images/903黄羊泉水库.png';
  import icon_27 from './images/904艾力克湖.png';
  import icon_28 from './images/泵站.png';
  import icon_29 from './images/701山上水库.png';
  import icon_30 from './images/绿.png';
  import icon_31 from './images/301-普通阀门_关.png';
  import icon_32 from './images/301-普通阀门_开.png'
  import icon_33 from './images/601-水泵_关.png';
  import icon_34 from './images/601-水泵_开.png';
  import defaultIcon from './images/home.png'

  ///////////////////////////////////////////////////////////////////////////

  export default {
    name: 'MyMap',
    props: ['mapInfo'],
    components: {
      DoubleBufferCanvas: DoubleBufferCanvas
    },
    data() {
      return {
        mouseX: 0,
        mouseY: 0,
        mouseEvent: null,
        messageInfo: '',
        messageWarning: '',
        messageError: '',
        enterNode: null,
        interval: null,
        iconSize: 40,
        fontSize: 10,
        fps: 5,
        borderSize: 50,
        canvasWidth: 0,
        canvasHeight: 0,
        doubleBufferCanvas1: null
      }
    },
    methods: {
      getIconByIconName(iconName) {
        if (!iconName || "" === iconName.trim()) {
          return null
        }
        iconName = iconName.replace("—", "-");


        ///////////////////////////////////////////////////////////////////////////
        if (iconName === '001用水区-输炼地区') {
          return icon_0;
        }
        if (iconName === '002用水区-石化园区') {
          return icon_1;
        }
        if (iconName === '002用水区域-石化园区') {
          return icon_2;
        }
        if (iconName === '003用水区-上环') {
          return icon_3;
        }
        if (iconName === '003用水区-自流环') {
          return icon_4;
        }
        if (iconName === '004用水区-白碱滩') {
          return icon_5;
        }
        if (iconName === '005用水区-下环') {
          return icon_6;
        }
        if (iconName === '006用水区-中环') {
          return icon_7;
        }
        if (iconName === '006用水区-乌尔禾') {
          return icon_8;
        }
        if (iconName === '007用水区') {
          return icon_9;
        }
        if (iconName === '1001泵站') {
          return icon_10;
        }
        if (iconName === '101水厂') {
          return icon_11;
        }
        if (iconName === '1101水源管理站') {
          return icon_12;
        }
        if (iconName === '201管汇间') {
          return icon_13;
        }
        if (iconName === '202管汇间') {
          return icon_14;
        }
        if (iconName === '301普通阀门') {
          return icon_15;
        }
        if (iconName === '302电控阀门') {
          return icon_16;
        }
        if (iconName === '401流量计') {
          return icon_17;
        }
        if (iconName === '501压力表') {
          return icon_18;
        }
        if (iconName === '601水泵') {
          return icon_19;
        }
        if (iconName === '701山顶水库') {
          return icon_20;
        }
        if (iconName === '801清水池') {
          return icon_21;
        }
        if (iconName === '901三坪水库') {
          return icon_22;
        }
        if (iconName === '901山坪水库') {
          return icon_23;
        }
        if (iconName === '902调节水库') {
          return icon_24;
        }
        if (iconName === '903黄羊水库') {
          return icon_25;
        }
        if (iconName === '903黄羊泉水库') {
          return icon_26;
        }
        if (iconName === '904艾力克湖') {
          return icon_27;
        }
        if (iconName === '泵站') {
          return icon_28;
        }
        if (iconName === '701山上水库') {
          return icon_29;
        }
        if (iconName === '绿') {
          return icon_30;
        }
        if (iconName === '301-普通阀门_关') {
          return icon_31;
        }
        if (iconName === '301-普通阀门_开') {
          return icon_32;
        }
        if (iconName === '601-水泵_关') {
          return icon_33;
        }
        if (iconName === '601-水泵_开') {
          return icon_34;
        }

        ///////////////////////////////////////////////////////////////////////////

        console.log('--------------->no found:' + iconName + "");
        return defaultIcon;
      },
      drawDebugPoint(context, x, y, radius = 10) {
        // drawArc(context, x, y, radius)
      },
      drawDebugRangeArea(context, x, y, width, height) {
        // context.strokeStyle = '#FF0000'
        // context.strokeRect(x, y, width, height)
      },
      drawNode(context, mapInfo, node, times = 1) {
        let x = node.x
        let y = node.y
        let name = node.name
        let iconName = node.iconName
        iconName = (iconName || iconName !== "") ? iconName : null
        let icon = iconName ? this.getIconByIconName(iconName) : null
        let iconWidth = iconName ? node.iconWidth : null
        let iconHeight = iconName ? node.iconHeight : null
        iconWidth = iconWidth * times
        iconHeight = iconHeight * times

        if (!icon) {
          context.fillStyle = '#f00'
          context.textAlign = 'center'
          context.textBaseline = 'middle'
          context.fillText(name, x, y)
        } else {
          let img = new Image()
          img.src = icon
          let iconX = x - iconWidth / 2
          let iconY = y - iconHeight / 2
          this.drawDebugPoint(context, x, y)
          img.onload = function () {
            context.drawImage(img, iconX, iconY, iconWidth, iconHeight)
          }
        }

        let drawNodeExt = node.drawNodeExt
        if (drawNodeExt) {
          drawNodeExt(context, node)
        }
      },
      drawLabels(context, mapInfo) {
        let labels = mapInfo.labels
        if (!labels) {
          return
        }
        // 绘制节点
        for (let index = 0; index < labels.length; index++) {
          let label = labels[index]
          let x = label.x
          let y = label.y
          this.drawDebugPoint(context, x, y)
          let name = label.name
          if (!name) {
            continue
          }
          context.fillStyle = '#f00'
          context.textAlign = 'center'
          context.textBaseline = 'middle'
          context.fillText(name, x, y)
        }
      },
      drawNodes(context, mapInfo) {
        let nodes = mapInfo.nodes
        if (!nodes) {
          return
        }
        // 绘制节点
        for (let index = 0; index < nodes.length; index++) {
          let node = nodes[index]
          this.drawNode(context, mapInfo, node)
        }
      },
      drawAreas(context, mapInfo) {
        let areas = mapInfo.areas
        if (!areas) {
          return
        }
        // 绘制节点
        for (let index = 0; index < areas.length; index++) {
          let area = areas[index]
          this.drawArea(context, area)
        }
      },
      drawArea(context, area) {
        let lineWidth = 1
        let lineColor = '#4A4AFF'
        let lines = area.lines
        lines.forEach(line => {
          let startPoint = line[0]
          let endPoint = line[1]
          let startX = startPoint.startX
          let startY = startPoint.startY
          let endX = endPoint.endX
          let endY = endPoint.endY

          context.save()
          context.setLineDash([10, 5])
          context.beginPath()
          context.moveTo(startX, startY)
          context.lineTo(endX, endY)
          context.lineWidth = lineWidth
          context.strokeStyle = lineColor
          context.lineCap = 'square'
          context.stroke()
          context.restore()
          this.drawDebugPoint(context, startX, startY)
        })
      },
      drawNodesBorder(context, mapInfo, mouseX = 0, mouseY = 0, divInfoWindow, mouseEvent) {
        let nodes = mapInfo.nodes
        if (!nodes) {
          return
        }
        let enterNode = null
        // 绘制节点
        for (let index = 0; index < nodes.length; index++) {
          let node = nodes[index]
          let showBorder = false
          // 判断鼠标是否在节点图标上面，只允许会进入一个node
          if (!enterNode && this.isMouseInNode(node, mouseX, mouseY)) {
            enterNode = node
            showBorder = true
          }
          if (showBorder) {
            let currentStrokeStyle = context.strokeStyle
            //放大图标
            let iconWidth = node.iconWidth
            let iconHeight = node.iconHeight
            let x = node.x
            let y = node.y
            x = x - iconWidth / 2
            y = y - iconHeight / 2
            context.strokeStyle = 'red'// 填充边框颜色
            context.strokeRect(x, y, iconWidth, iconHeight)// 对边框的设置
            context.strokeStyle = currentStrokeStyle
          }
        }
        if (enterNode) {
          this.enterNode = enterNode
          this.messageWarning = '进入节点:' + enterNode.name
          CanvasUtil.divSetVisible(divInfoWindow, true)
          //放大图标
          let iconWidth = enterNode.iconWidth
          let iconHeight = enterNode.iconHeight
          let divX = mouseEvent.clientX + iconWidth / 2//canvas margin 20px，所以要偏移20px
          let divY = mouseEvent.clientY + iconHeight / 2
          CanvasUtil.divAbsolutePositionResetByMouseEvent(divInfoWindow, divX, divY)
          CanvasUtil.divSetInnerHTML(divInfoWindow, this.messageWarning)
        } else {
          this.enterNode = null
          CanvasUtil.divSetVisible(divInfoWindow, false)
        }
      },
      drawFlashLine(context, mapInfo) {
        let flashLines = mapInfo.flashLines
        if (!flashLines) {
          return
        }

        flashLines.forEach(flashLine => {
          flashLine = CanvasUtil.flashLineUpdate(flashLine)
          CanvasUtil.flashLineDraw(flashLine, context, 'blue')
        })
      },
      logInfo(context, message) {
        message = message || ''
        CanvasUtil.drawText(context, message, 10, 20, 15, 'black')
      },
      logWarning(context, message) {
        message = message || ''
        CanvasUtil.drawText(context, message, 10, 40, 15, 'blue')
      },
      logError(context, message) {
        message = message || ''
        CanvasUtil.drawText(context, message, 10, 60, 15, 'red')
      },
      isMouseInNode(node, mouseX, mouseY) {
        let x = node.x
        let y = node.y
        let iconName = node.iconName
        if (!iconName) {
          return false
        }

        let iconWidth = node.iconWidth
        let iconHeight = node.iconHeight
        let iconX = x - iconWidth / 2
        let iconY = y - iconHeight / 2
        // 判断鼠标是否在节点图标上面，只允许会进入一个node
        if (iconX < mouseX && iconY < mouseY && mouseX < (iconX + iconWidth) && mouseY < (iconY + iconHeight)) {
          return true
        }
        return false

      },
      getEnterNode(mapInfo, mouseX, mouseY) {
        let nodes = mapInfo.nodes
        let enterNode = null
        // 绘制节点
        for (let index = 0; index < nodes.length; index++) {
          let node = nodes[index]
          // 判断鼠标是否在节点图标上面，只允许会进入一个node
          if (!enterNode && this.isMouseInNode(node, mouseX, mouseY)) {
            enterNode = node
            break
          }
        }
        return enterNode
      },
      initMap() {
        let canvas0 = document.getElementById('canvas0')
        this.doubleBufferCanvas1 = this.$refs.doubleBufferCanvas1
        let canvas2 = document.getElementById('canvas2')

        // resizeCanvas(canvas0)
        // resizeCanvas(canvas1)
        // resizeCanvas(canvas2)
        // this.doubleBufferCanvas1 = this.$.refs.doubleBufferCanvas1

        CanvasUtil.resizeCanvas(canvas0, 0, 0)
        this.doubleBufferCanvas1.resize(0, 0)
        CanvasUtil.resizeCanvas(canvas2, 0, 0)
        this.canvasWidth = canvas0.width
        this.canvasHeight = canvas0.height
      },
      getBasicMapInfo() {
        let basicMapInfo = {
          iconSize: this.iconSize,
          canvasWidth: this.canvasWidth,
          canvasHeight: this.canvasHeight,
          borderSizeX: this.borderSize,
          borderSizeY: this.borderSize,
          fps: this.fps,
          fontSize: this.fontSize
        }
        return basicMapInfo
      }
      ,
      updateMapInfo(mapInfo) {
        let iconSize = mapInfo.iconSize
        let fps = mapInfo.fps
        let fontSize = mapInfo.fontSize

        clearInterval(this.interval)


        let canvas0 = document.getElementById('canvas0')
        let doubleBufferCanvas1 = this.doubleBufferCanvas1
        let canvas2 = document.getElementById('canvas2')

        let context0 = canvas0.getContext('2d')
        let context2 = canvas2.getContext('2d')

        let divInfoWindow = document.getElementById('infoWindow')

        canvas2.onmousemove = (e) => {
          let location = CanvasUtil.windowToCanvas(canvas2, e.clientX, e.clientY)
          let mouseX = location.x
          let mouseY = location.y

          this.messageWarning = "mouseX:" + mouseX + "," + mouseY
          this.mouseX = mouseX
          this.mouseY = mouseY
          this.mouseEvent = e
        }

        canvas2.onmousedown = (e) => {
          let location = CanvasUtil.windowToCanvas(canvas2, e.clientX, e.clientY)
          let mouseX = location.x
          let mouseY = location.y
          let enterNode = this.getEnterNode(mapInfo, mouseX, mouseY)
          if (enterNode) {
            this.messageError = '当前选中:' + enterNode.name
            this.$emit("onClickNode", enterNode)
          } else {
            this.messageError = '没有选中任何节点'
          }
        }

        let timestamp1 = new Date().getTime()
        let canvas = this.doubleBufferCanvas1.beginDrawing()
        let context = canvas.getContext('2d')

        this.drawLabels(context, mapInfo)
        this.drawNodes(context, mapInfo)
        this.drawAreas(context, mapInfo)

        // 双缓冲绘制 隐藏掉当前图层，绘制完成之后，
        this.doubleBufferCanvas1.finishDrawing()


        this.interval = setInterval(() => {
          CanvasUtil.cleanCanvas(canvas0)
          CanvasUtil.cleanCanvas(canvas2)

          let timestamp2 = new Date().getTime()
          let timeFps = (timestamp2 - timestamp1) / 1000
          timestamp1 = timestamp2
          let fps = Math.ceil(1 / timeFps)
          this.messageInfo = 'fps: ' + fps

          this.logInfo(context2, this.messageInfo)
          this.logWarning(context2, this.messageWarning)
          this.logError(context2, this.messageError)

          let mouseX = this.mouseX ? this.mouseX : 0
          let mouseY = this.mouseY ? this.mouseY : 0
          let mouseEvent = this.mouseEvent
          this.drawFlashLine(context0, mapInfo, 0, 0, iconSize, fontSize)
          this.drawNodesBorder(context2, mapInfo, mouseX, mouseY, divInfoWindow, mouseEvent)
        }, 1000 / fps)
      }
    },
    mounted() {
      this.initMap()
      let basicMapInfo = this.getBasicMapInfo()
      this.$emit("postInitMap", basicMapInfo)//
    },
    watch: {
      mapInfo() {
        let mapInfo = this.mapInfo
        this.updateMapInfo(mapInfo)
      }
    }
  }
</script>
<style scoped>
  #canvas0 {
    position: absolute;
    left: 0px;
    top: 0px;
    margin: 20px;
    border: thin solid #aaaaaa;
    z-index: 1;
  }

  #canvas1 {
    position: absolute;
    left: 0px;
    top: 0px;
    margin: 20px;
    border: thin solid #aaaaaa;
    z-index: 2;
  }

  #canvas2 {
    position: absolute;
    left: 0px;
    top: 0px;
    margin: 20px;
    border: thin solid #aaaaaa;
    z-index: 3;
  }

  #infoWindow {
    position: absolute;
    left: 0px;
    top: 0px;
    width: 200px;
    height: 200px;
    border-radius: 2px;
    border: 2px solid blue;
    z-index: 4;
  }
</style>
